Handles the creation, reading, deletion overall management of secret vaults.

Types

PublicKeyFile

Represents a reference to an encrypted secret file.

  • Fields:

    • string SecretName (internal set): Logical name of the secret.
    • string SecretPath (internal set): Encrypted path to the secret file.
  • Constructor:

    PublicKeyFile(string secretName, string secretPath)


PublicKeyFileInit

Used to initialize a new secret entry when creating a bank.

  • Fields:

    • string SecretName (internal set): Logical name of the secret.
    • SecureString Value (internal set): Initial secret value.
    • SecureString? SecretPath (internal set): Optional custom directory path.
  • Constructor:
    PublicKeyFileInit(string secretName, SecureString? secretPath, SecureString value)


Methods

CreateBank(string BankDirectory, string BankName, List? PublicKeys, string? PublicDecryptKey)

Creates a “bank” JSON file listing public secrets, and optionally initializes individual secret files.

  • Parameters:

    • BankDirectory: Folder in which to store the bank JSON.
    • BankName: Name of the bank (JSON filename without extension).
    • PublicKeys: Optional list of initial secrets to create.
    • PublicDecryptKey: Optional decryption key (defaults to board serial).
  • Returns: Task

  • Exceptions:

    • Exception if bank already exists or on any file I/O error.

CheckIfBankExists(string BankDirectory, string BankName)

Checks for the existence of the bank JSON file.

  • Parameters:

    • BankDirectory
    • BankName
  • Returns: Task — true if the bank file exists.


GetPublicSecret(string BankDirectory, string BankName, string PublicSecretName, string? PublicDecryptKey, string? SecretDecryptKey)

Retrieves and decrypts a public secret value from a bank.

  • Parameters:

    • BankDirectory, BankName
    • PublicSecretName: Logical name of the secret to retrieve.
    • PublicDecryptKey: Key to decrypt the bank index (defaults to board serial).
    • SecretDecryptKey: Key to decrypt the individual secret (defaults to same as public key).
  • Returns: Task — Decrypted secret value.

  • Exceptions:

    • Exception if secret not found or on decryption errors.

GetSecretRound(string BankDirectory, string BankName, string PublicSecretName, string? PublicDecryptKey)

Reads the “Pneumentations” (rotation count) for a public secret.

  • Parameters: Same as GetPublicSecret minus SecretDecryptKey.

  • Returns: Task — Current rotation count.


AddPublicSecret(string BankDirectory, string BankName, PublicKeyFileInit PublicSecret, string? PublicDecryptKey)

Adds a new secret to an existing bank, creating its file and encrypting its initial value.

  • Parameters:

    • PublicSecret: Initialization data for the new secret.
    • Others as in CreateBank.
  • Returns: Task


DeletePublicSecret(string BankDirectory, string BankName, string PublicSecretName, string? PublicDecryptKey)

Removes a secret entry from both the bank JSON and deletes its file.

  • Parameters:

    • PublicSecretName
    • Others as in GetPublicSecret
  • Returns: Task


GetAllSecretNames(string BankDirectory, string BankName, string? PublicDecryptKey)

Lists all logical secret names in the bank.

  • Returns: Task<List>

RotateSecret(string BankDirectory, string BankName, string PublicSecretName, string? salt, string? PublicDecryptKey, string? newSalt)

Rotates (re-hashes) a secret’s value, updates its “Pneumentations” count, and writes back.

  • Parameters:

    • salt: Existing salt or key for rotation.
    • newSalt: If provided, resets the salt and count.
    • Others as in GetPublicSecret
  • Returns: Task — New rotated secret.


MigratePublicSecrets(string BankDirectory, string BankName, Dictionary<string,(SecureString? OldPassword, SecureString? NewPassword, string NewPath)> secretMigrations, string newBankDirPath, string? NewFileDirectoryPath, SecureString OldPublicDecryptKey, SecureString? NewPublicDecryptKey)

WIP — Re-encrypts and/or moves existing secrets to a new bank directory with optional password/key changes.

  • Parameters:

    • secretMigrations: Map of secret names to old/new key pairs and new file locations.
    • newBankDirPath, NewFileDirectoryPath
    • OldPublicDecryptKey, NewPublicDecryptKey
  • Returns: Task

  • Notes: Not production-ready; use with caution.


DataHandler.SecretManager

Tests all of the Accounts system, remember to set the directory!

          public async Task AccountsTest()
          {
              var directory = @"TestFiles\";

              await accounts.SetupFiles(directory);

              var newUser = await accounts.CreateUser("RedEyedXaXa", "GGO_NoRespawn$SinonTargeted@Midnight".ToSecureString(true), directory);

              Console.WriteLine("New User Created, password recovery key: " + newUser.ConvertToString());

              var loginUser = await accounts.LoginUser("RedEyedXaXa", directory, "GGO_NoRespawn$SinonTargeted@Midnight".ToSecureString(true));

              Console.WriteLine("Login User File Encryption Key: " + loginUser.ConvertToString());

              var resetTest = await accounts.ResetPassword("RedEyedXaXa", directory, "XeXeed_Offline$KillCode_2077*VR".ToSecureString(true), newUser);

              Console.WriteLine("Password Reset Key: " + resetTest.ConvertToString());
          }

PariahCybersecTest.AccountsTest

Turns a byteArray back into a string using BinaryConverter.ByteArrayToObjectAsync

           public async Task<string> FromByte(byte[] byteArray)
           {
               return await BinaryConverter.ByteArrayToObjectAsync<string>(byteArray);
           }

BinaryConverterTest.FromByte

Turns an Operation object into bytes before turning it back into an Operation and ensuring the values are still as they should be.

            public async void TestObjectToByteArrayAsync()
            {

                BinaryConverter binaryConverter = new BinaryConverter();

                Operation operation = new Operation();

                // Convert the operation object to a byte array

                byte[] byteArray = await BinaryConverter.ObjectToByteArrayAsync(operation);

                Console.WriteLine("Byte array length: " + byteArray.Length);

                // Convert the byte array back to an object

                Operation convertedOperation = await BinaryConverter.ByteArrayToObjectAsync<Operation>(byteArray);

                Console.WriteLine("Converted Operation Name: " + convertedOperation.OperationName);
                Console.WriteLine("Converted Description: " + convertedOperation.Description);
                Console.WriteLine("Converted Yorha Sect: " + convertedOperation.YorhaSect);
                Console.WriteLine("Converted IsActive: " + convertedOperation.IsActive);
                Console.WriteLine("Converted MaxLevel: " + convertedOperation.MaxLevel);
                Console.WriteLine("Converted Difficulty: " + convertedOperation.Difficulty);
                Console.WriteLine("Converted AttackSpeed: " + convertedOperation.AttackSpeed);
                Console.WriteLine("Converted CreatedAt: " + convertedOperation.CreatedAt);
                Console.WriteLine("Converted Operators Count: " + convertedOperation.Operators.Count);
                Console.WriteLine("Converted Enemies Count: " + convertedOperation.Enemies.Count);
                Console.WriteLine("Converted Weapons Count: " + convertedOperation.Weapons.Count);

                //Newline spacer

                Console.WriteLine(Environment.NewLine);
                Console.WriteLine(Environment.NewLine);

            }

BinaryConverterTest.TestObjectToByteArrayAsync

Turns a string into a byte array using the BinaryConverter.ObjectToByteArrayAsync method

    public async Task<byte[]> ToByte()
        {
            return await BinaryConverter.ObjectToByteArrayAsync("This is a test string.");
        }

BinaryConverterTest.ToByte

Provides methods to serialize, encrypt, decrypt, and deserialize objects using JSON + AES.

Shared Settings

  • _jsonOpts (JsonSerializerOptions):
    • IncludeFields = true
      Enables JSON serialization of public fields as well as properties.

Methods

PackData(object data, SecureString Key)

Serializes an object of type T to JSON, wraps it with its assembly-qualified type name, Base64-encodes, then encrypts via AES-GCM.

  • Parameters:

    • data: The object to serialize (must be castable to T).
    • Key: SecureString used to derive the AES encryption key.
  • Process:

    1. Convert data to a byte array via BinaryConverter.NCObjectToByteArrayAsync.
    2. Create a tuple (assemblyQualifiedTypeName, payloadBytes).
    3. Serialize the tuple to UTF-8 JSON bytes (JsonSerializer.SerializeToUtf8Bytes).
    4. Base64-encode the JSON bytes.
    5. Encrypt the Base64 string using SimpleAESEncryption.Encrypt.
    6. Return the encrypted payload as AESEncryptedText.ToString().
  • Returns: Task — The encrypted Base64 JSON wrapper as a single string.


UnpackData(string data, SecureString Key)

Decrypts and deserializes a string previously produced by PackData back into the original object.

  • Parameters:

    • data: The encrypted payload string (IV|EncryptedText format).
    • Key: SecureString used to derive the AES decryption key.
  • Process:

    1. Parse data into SimpleAESEncryption.AESEncryptedText.
    2. Decrypt to recover the Base64-encoded JSON wrapper.
    3. Base64-decode to JSON bytes.
    4. Deserialize JSON into (string assemblyQualifiedTypeName, byte[] payloadBytes).
    5. Resolve the Type from assemblyQualifiedTypeName.
    6. Use reflection to call BinaryConverter.NCByteArrayToObjectAsync on payloadBytes.
    7. Await and return the .Result of that task (the original object).
  • Returns: Task — The deserialized object instance.

  • Exceptions:

    • Throws if decryption fails, JSON is invalid, the type cannot be resolved, or deserialization errors occur.

DataHandler.DataEncryptions

A system focused on creating a reliable system for data sharing between programs (outside of named pipes).

Types

SecuritySettings

Global configuration for directory- and session-related timeouts and keys.

  • Properties (static):

    • SecureString PublicKey — Key used to encrypt/decrypt metadata (default "Default").
    • double ExpiryDuration — Untrusted session/file validity in minutes (default 540).
    • double TrustedExpiryDuration — Trusted validity in minutes (default 20160).
    • int FailRecoveryCheck — Max allowed recovery failures before lockout (default 5).
    • double TimeToNextRecovery — Lockout duration in minutes after too many failures (default 20).
  • Methods (static):

    • SetPublicKey(string newKey, bool makeReadOnly = true)
    • SetExpiryDuration(double minutes)
    • SetTrustedExpiryDuration(double minutes)
    • SetFailRecoveryCheck(int count)
    • SetTimeToNextRecovery(double minutes)

DirectoryData

Holds common filesystem paths for a given “service” installation.

  • Properties:

    • string CompanyPath
    • string MainServicePath
    • string ServiceParent
    • string Author
    • string Software
    • string UserSharedResources
    • string UserFolder
    • string ExePath
    • string Program
  • Constructors:
    DirectoryData() { }
    DirectoryData(
    string companyPath,
    string mainServicePath,
    string serviceParent,
    string author,
    string software,
    string userSharedResources,
    string userFolder,
    string exePath,
    string program
    )


EncryptedTier

Encapsulates a per-tier encrypted key and its signatures.

  • Properties:

    • byte[] SignedEncryptedTier — Signature over the tier identifier.
    • string EncryptedTierPass — AES-encrypted tier password (Base64).
    • byte[] SignedTierPass — Signature over the raw tier password.
  • Constructors:
    EncryptedTier() { }
    EncryptedTier(byte[] signedEncryptedTier, string encryptedTierPass, byte[] signedTierPass)


Methods

GetExecutablePathAsync(string command)

Finds the full path of an executable on the system.

  • Parameters:
    • command: The program name (e.g. "dotnet").
  • Returns: Task<string?> — First matching path, or null if not found.

IsFileWithinDirectoryAsync(string filePath, string baseDirectory)

Checks whether filePath resides under baseDirectory.

  • Parameters:
    • filePath, baseDirectory.
  • Returns: Task.

GetPaths(SecureString identifier, string software, string author, string programName, string serviceParent)

Builds standard folder layout under %LocalAppData%{author}.

  • Parameters:
    • identifier: User or instance ID.
    • software, author, programName, serviceParent.
  • Returns: Task with all constructed paths.

CheckMainPathValidity(DirectoryData data, SecureString? PublicKey)

Verifies “CORE.json” integrity by checking a signed “mother path” entry.

  • Parameters:
    • data: DirectoryData containing MainServicePath.
    • PublicKey: Key to decrypt and verify signatures.
  • Returns: Task.

ValidateProgram(DirectoryData data, string programName, SecureString? PublicKey)

Ensures the executable for programName resides within MainServicePath.

  • Returns: Task.

CreateNewSystem(string username, SecureString identifier, SecureString password, string software, string author, string exePath, string serviceParent, int tiers, SecureString? PublicKey)

Bootstraps a brand-new “service” instance:

  1. Creates directory hierarchy under %LocalAppData%{author}{serviceParent}{software}.
  2. Writes CORE.json containing public key and signatures for service path & author.
  3. Creates a secret-bank (SecretManager.CreateBank) under UserSharedResources.
  4. Generates tiers number of encrypted tier keys & signatures, saves to Data Tiers.json.
  5. Initializes Allowed Programs and Blacklisted Programs JSON files.
  6. Delegates user/account creation via AccountsWithSessions.
  • Returns: Task — Recovery key or session identifier from the created account.

CreateNewApp(string username, SecureString password, string Directory, DirectoryData directories, string tier, SecureString? PublicKey)

Registers a new application under an existing “service”:

  1. Validates main service signature and path.
  2. Checks that directories.Software is not blacklisted.
  3. Verifies tier signature from Data Tiers.json.
  4. Adds the app to Allowed Programs.json.
  5. Invokes CreateUser in the service’s directory.
  • Returns: Task — Recovery/session key for the new app account.

AddToBlacklist(string softwareName, ConnectedSessionReturn connSession, string mainServicePath, SecureString PublicKey)

Marks a program as blacklisted:

  • Throws: if already blacklisted.

RemoveFromBlacklist(string softwareName, ConnectedSessionReturn connSession, string mainServicePath, SecureString PublicKey)

Removes a program from the blacklist:

  • Throws: if not present.

RemoveAccount(string softwareName, ConnectedSessionReturn connSession, string mainServicePath, SecureString PublicKey)

Removes an allowed program entry:

  • Throws: if the program is not in Allowed Programs.json.

VerifySessionIntegrity(DirectoryData data, ConnectedSessionReturn connSession, string mainServicePath, SecureString PublicKey)

Composite check that both:

  1. Main path validity (CheckMainPathValidity), and
  2. Session validity (ValidateSession from AccountsWithSessions),

are still intact. Throws on failure.


DataHandler.DataRequest

DeviceIdentifier Class

Retrieves a machine-unique board serial number across Windows, Linux, and macOS by executing platform-specific commands.


Methods

GetBoardSerialAsync()

Detects the current OS and invokes the appropriate system command to fetch the motherboard’s serial number.

  • Returns: Task
    • On Windows: runs wmic baseboard get serialnumber.
    • On Linux: reads /sys/class/dmi/id/board_serial via cat.
    • On macOS: uses ioreg -l | awk -F'"' '/IOPlatformSerialNumber/ {print $4}'.
    • On other platforms: returns "Unsupported OS".

RunCommandAsync(string fileName, string arguments)

Helper that executes a shell command and returns its last non-empty output line.

  • Parameters:
    • fileName: The command or executable to run (e.g., wmic, cat, ioreg).
    • arguments: Arguments or flags for the command.
  • Returns: Task — The trimmed last line of standard output, or an error message on failure.

DataHandler.DeviceIdentifier

Types

PariahJSON

Represents a JSON file on disk along with its parsed data.

  • Fields:

    • string FileName (read-only): The name of the JSON file (without extension).
    • string FilePath (internal set): The directory path where the file resides.
    • JObject Data (read-only): The parsed JSON content.
  • Constructor:
    csharp
    PariahJSON(string fileName, string filePath, JObject data)

Initializes a new instance with the given file name, file path, and JSON data.


Methods

CreateJsonFile(string Filename, string FileLocation, JObject defaultData)

Creates a new .json file containing the provided default data.

  • Parameters:
    • Filename: Name of the file (without “.json”).
    • FileLocation: Directory in which to create the file.
    • defaultData: The JObject to write as the file’s initial contents.
  • Returns: Task
  • Exceptions:
    • Exception if the directory doesn’t exist or a file with the same name already exists.
    • Wraps any write errors in a generic Exception with an explanatory message.

LoadJsonFile(string Filename, string FileLocation)

Loads and parses an existing .json file into a PariahJSON struct.

  • Parameters:
    • Filename: Name of the file (without “.json”).
    • FileLocation: Directory where the file resides.
  • Returns: Task< PariahJSON > containing the file’s name, path, and parsed JObject.
  • Exceptions:
    • Exception if the directory or file doesn’t exist, or on read/parse errors.

AddToJson(PariahJSON JsonData, string dataName, object data, SecureString? Key)

Encrypts and adds a new data field to the in-memory JSON.

  • Parameters:
    • JsonData: Existing PariahJSON instance.
    • dataName: JSON property name to add.
    • data: The object to serialize & encrypt.
    • Key: Optional SecureString key for encryption; defaults to "skibidi" if null.
  • Returns: Task< PariahJSON > with the updated JSON (does not write to disk).

DeletefromJson(PariahJSON JsonData, string dataName)

Removes a property from the in-memory JSON.

  • Parameters:
    • JsonData: Existing PariahJSON instance.
    • dataName: JSON property name to remove.
  • Returns: PariahJSON with the property removed (does not write to disk).

UpdateJson(PariahJSON JsonData, string dataName, object data, SecureString? Key)

Replaces an existing JSON property with new encrypted data.

  • Parameters:
    • JsonData: Existing PariahJSON instance.
    • dataName: JSON property name to update.
    • data: The new object to serialize & encrypt.
    • Key: Optional SecureString key for encryption; defaults to "skibidi" if null.
  • Returns: Task< PariahJSON > with the updated JSON (does not write to disk).

GetVariable(PariahJSON JsonData, string dataName, SecureString? Key)

Retrieves and decrypts a previously added JSON property.

  • Parameters:
    • JsonData: Existing PariahJSON instance.
    • dataName: JSON property name to retrieve.
    • Key: Optional SecureString key for decryption; defaults to "skibidi" if null.
  • Returns: Task< object > — The decrypted object.
  • Exceptions:
    • Exception if the property is missing or not a string, or on decryption errors.

CheckIfVariableExists(PariahJSON JsonData, string dataName)

Checks whether a given property exists and is a string.

  • Parameters:
    • JsonData: Existing PariahJSON instance.
    • dataName: JSON property name to check.
  • Returns: Task< bool >

SaveJson(PariahJSON JsonData)

Serializes and writes the in-memory JSON back to its original file location.

  • Parameters:
    • JsonData: The PariahJSON holding the file name, path, and updated data.
  • Returns: Task
  • Exceptions:
    • Exception if the directory or file doesn’t exist or on write errors.

DataHandler.JSONDataHandler

Handles the Salting and Hashing of Data

Types

PasswordCheckData

Holds the salt and hash produced when generating a password hash.

  • Fields:

    • string SaltKey (get/set): Base64-encoded salt.
    • string HashKey (get/set): Base64-encoded hash.
  • Constructor:
    PasswordCheckData(string saltKey, string hashKey)

Initializes both fields.


PasswordHandler

Provides methods to generate and validate password hashes using Argon2id with a cryptographically secure salt.


Methods

GeneratePasswordHashAsync(SecureString password, int iterations = 4, int saltByteSize = 64, int hashByteSize = 128)

Creates a new random salt and computes an Argon2id hash of the given password.

  • Parameters:
    • password: The user’s password as a SecureString.
    • iterations: Number of Argon2id iterations (default: 4).
    • saltByteSize: Length in bytes of the random salt (default: 64).
    • hashByteSize: Desired length in bytes of the hash output (default: 128).
  • Returns: Task containing Base64-encoded SaltKey and HashKey.

ValidatePasswordAsync(SecureString password, PasswordCheckData passValues, int iterations = 4, int hashByteSize = 128)

Verifies a password by re-computing its Argon2id hash with the stored salt and comparing securely.

  • Parameters:
    • password: The password to validate as a SecureString.
    • passValues: The stored SaltKey and HashKey.
    • iterations: Number of Argon2id iterations used when generating the hash (default: 4).
    • hashByteSize: Length in bytes of the expected hash (default: 128).
  • Returns: Task — true if the computed hash matches the stored hash.

Argon2_GetHashAsync(SecureString password, byte[] salt, int iterations, int hashByteSize)

Internal helper that runs Argon2id synchronously within a Task to produce a raw hash byte array.

  • Parameters:
    • password: The password as SecureString.
    • salt: The raw salt bytes.
    • iterations: Argon2id iteration count.
    • hashByteSize: Desired hash byte length.
  • Returns: Task<byte[]> — The raw hash bytes.

SlowEquals(byte[] a, byte[] b)

Performs a constant-time comparison between two byte arrays to prevent timing attacks.

  • Parameters:
    • a: First byte array.
    • b: Second byte array.
  • Returns: bool — true if arrays are identical length and contents.

Notes

  • Uses BouncyCastle’s SecureRandom for salt generation.
  • Argon2id parameters (memory size, parallelism) are tuned for moderate security/performance; adjust as needed.
  • Always use SecureString to minimize plaintext exposure in memory.
DataHandler.SaltAndHashing

A barebones local account system

Types

AccountData

Represents a user account’s stored data.

  • Properties:

    • string Username
    • PasswordCheckData Password
    • string DataEncryptionKey
    • string RecoveryDataKey
  • Constructors:
    AccountData() { } // For deserialization
    AccountData(string username,
    PasswordCheckData password,
    string dataEncryptionKey,
    string recoveryDataKey)


Fields & Helpers

  • internal SecureString PublicKey
    Default key used to encrypt/decrypt the account list JSON.

  • internal void ChangePublicKey(string NewVal)
    Updates PublicKey to a new value (wrapped in SecureString).


Methods

SetupFiles(string directory)

Initializes a fresh “Users.json” in the specified directory containing an empty account list.

  • Parameters:

    • directory: Path to the folder where Users.json will be created.
  • Returns: Task


CreateUser(string username, SecureString password, string Directory)

Creates a new user entry, storing:

  1. A salted & hashed password (PasswordCheckData).
  2. A random data-encryption key encrypted under the user’s password.
  3. A recovery key encrypted under the data-encryption key.
  • Parameters:

    • username: Desired username (must be unique).
    • password: User’s chosen password.
    • Directory: Path containing Users.json.
  • Returns: Task — The recovery key (for password resets).

  • Exceptions:

    • If username already exists.

LoginUser(string username, string Directory, SecureString password)

Validates credentials and, on success, returns the user’s data-encryption key.

  • Parameters:

    • username, Directory, password.
  • Returns: Task — Decrypted data-encryption key.

  • Exceptions:

    • If user not found or password invalid.
    • Wraps I/O or decryption errors.

ResetPassword(string username, string Directory, SecureString newpassword, SecureString RecoveryPass)

Uses the stored recovery key to re-encrypt a new password and rotation of encryption keys:

  1. Decrypts existing data-encryption key via RecoveryPass.
  2. Generates a fresh hash for newpassword.
  3. Creates a new encryption key & recovery key pair.
  4. Updates the AccountData entry.
  • Parameters:

    • username, Directory
    • newpassword: The new password to set.
    • RecoveryPass: The previously returned recovery key.
  • Returns: Task — The new data-encryption key.

  • Exceptions:

    • If recovery fails or user not found.

DataHandler.Accounts

A more robust account system with token verification, session checks, expiries, etc.

markdown

Types

ActiveSession

Represents a user’s active session record.

  • Properties:

    • string Username — User’s name.
    • string SessionID — Unique session identifier.
    • string SessionKey — Encrypted session key.
    • string Expiry — UTC expiry timestamp in ISO-8601 ("o") format.
    • string IsTrusted — Encrypted payload of Expiry|IsTrustedFlag.
    • string ChecksAndLastTry — Encrypted payload of FailedRecoveryCount|LastAttemptUtc.
  • Constructors:
    ActiveSession() { }
    ActiveSession(string username,
    string sessionID,
    string sessionKey,
    string expiry,
    string isTrusted,
    string checksAndLastTry)


ConnectedSessionReturn

Encapsulates the decrypted session details returned to the caller.

  • Properties (all SecureString):

    • Username
    • SessionKey
    • SessionID
    • Directory — Path to the user-data directory.
  • Constructors:
    ConnectedSessionReturn() { }
    ConnectedSessionReturn(string username,
    string sessionKey,
    string sessionID,
    SecureString directory)


ReturnCreateUser

Holds both the initial session info and recovery key when creating a new user.

  • Properties:

    • ConnectedSessionReturn sessionReturn
    • SecureString RecoveryKey
  • Constructors:
    ReturnCreateUser() { }
    ReturnCreateUser(ConnectedSessionReturn sessionReturn,
    SecureString recoveryKey)


SecuritySettings

Global configuration for session lifetimes and recovery policies.

  • Properties (static):

    • SecureString PublicKey — Key used to encrypt session store.
    • double ExpiryDuration — Untrusted session lifetime in minutes (default 540).
    • double TrustedExpiryDuration — Trusted session lifetime in minutes (default 20160).
    • int FailRecoveryCheck — Max allowed recovery failures before lockout (default 5).
    • double TimeToNextRecovery — Lockout duration in minutes (default 20).
  • Methods (static):

    • SetPublicKey(string newKey, bool makeReadOnly = true)
    • SetExpiryDuration(double minutes)
    • SetTrustedExpiryDuration(double minutes)
    • SetFailRecoveryCheck(int count)
    • SetTimeToNextRecovery(double minutes)

AccountData

Same as in Accounts, stores per-user credentials and encryption keys.

  • Properties:

    • string Username
    • PasswordCheckData Password
    • string DataEncryptionKey
    • string RecoveryDataKey
  • Constructors:
    AccountData() { }
    AccountData(string username,
    PasswordCheckData password,
    string dataEncryptionKey,
    string recoveryDataKey)


Methods

SetupFiles(string directory)

Initializes Users.json with empty AccountsList and empty Sessions arrays.

  • Parameters:

    • directory: Path to the folder for Users.json.
  • Returns: Task


CreateUser(string username, SecureString password, string Directory)

Registers a new user and returns a recovery key.

  • Steps:

    1. Load existing AccountsList.
    2. Ensure username is unique.
    3. Hash password (PasswordHandler).
    4. Generate a random data-encryption key & recovery key.
    5. Encrypt data key under password, and recovery key under data key.
    6. Append new AccountData, save JSON.
  • Returns: Task — The recovery key.

  • Exceptions: If username already exists.


LoginUser(string username, string Directory, SecureString password, bool IsTrusted)

Authenticates credentials and creates a new session.

  • Parameters:

    • username, Directory, password, IsTrusted flag.
  • Process:

    1. Validate via private LoginCore.
    2. Generate sessionKey & sessionID.
    3. Encrypt sessionKey under data key.
    4. Compute expiry based on IsTrusted.
    5. Encrypt IsTrusted|expiry and initial ChecksAndLastTry.
    6. Append new ActiveSession to Sessions array, save JSON.
  • Returns: Task<(SecureString dataKey, ConnectedSessionReturn sessionInfo)>

  • Exceptions: On invalid credentials or I/O errors.


ValidateSession(ConnectedSessionReturn connSession, SecureString decryptKey)

Checks session validity, expiry, and integrity; extends expiry if valid.

  • Parameters:

    • connSession: Decrypted session info.
    • decryptKey: Data-encryption key from login.
  • Process:

    1. Load Sessions and locate matching record.
    2. If expired, remove it, save JSON, return false.
    3. Decrypt and verify SessionKey and IsTrusted|expiry consistency.
    4. If tampered, remove and throw exception.
    5. Extend expiry, update encrypted session record, save JSON.
    6. Return true.
  • Exceptions: On tampering or parsing errors.


LogoutUser(ConnectedSessionReturn connSession, SecureString decryptKey)

Invalidates a session immediately.

  • Process: Calls ValidateSession (throws if invalid), then removes the session record and saves JSON.

  • Returns: Task


RemoveAccount(ConnectedSessionReturn connSession, SecureString decryptKey)

Deletes a user account and all its sessions.

  • Process:

    1. Validate session and logout.
    2. Remove the matching AccountData from AccountsList.
    3. Save JSON.
  • Returns: Task


ResetPassword(ConnectedSessionReturn connSession, SecureString decryptKey, SecureString NewPassword, SecureString RecoveryPass)

Allows password reset from within an active session, enforcing recovery-policy limits.

  • Process:

    1. Validate session.
    2. Load AccountData and matching ActiveSession.
    3. Decrypt ChecksAndLastTry and RecoveryDataKey.
    4. Enforce failure count & lockout timings.
    5. Generate new password hash, encryption key & recovery key.
    6. Update AccountData, reset ChecksAndLastTry.
    7. Invalidate existing session(s), save JSON.
  • Returns: Task

  • Exceptions: On recovery key failures or policy triggers.


GetAllUsernames(ConnectedSessionReturn connSession, SecureString decryptKey)

Returns the list of all registered usernames.

  • Parameters:

    • connSession, decryptKey.
  • Returns: Task<List>


DataHandler.AccountsWithSessions

Tests all of the AccountsWithSessions system

            public static async Task AccountsWithSessionsTest()
            {
                var directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "PariahCybersecTest", "TestFilesAsync");

                if (Directory.Exists(directory))
                {
                    Directory.Delete(directory, true); // `true` means recursive deletion
                    Console.WriteLine("Directory and its contents reset.");
                }

                Directory.CreateDirectory(directory);

                Console.WriteLine(directory);
                string username = "testUser";
                SecureString password = "testPassword123".ToSecureString(true); // Convert to SecureString
                string recoveryPassword = "recoveryPassword123"; // Recovery password

                // Initialize the object that has the methods
                var userManagement = new DataHandler.AccountsWithSessions();

                // Setup files (Initialize JSON structure)
                await userManagement.SetupFiles(directory);

                // Create a user
                SecureString recoveryKey = await userManagement.CreateUser(username, password, directory);
                Console.WriteLine($"User created. Recovery key: {recoveryKey.ConvertToString()}");

                // Login the user
                var loginResult = await userManagement.LoginUser(username, directory, password, true);
                Console.WriteLine($"User logged in. Session ID: {loginResult.Item2.SessionID}");

                // Validate the session
                bool isSessionValid = await userManagement.ValidateSession(loginResult.Item2, loginResult.Item1);
                Console.WriteLine($"Is session valid: {isSessionValid}");

                // Reset password
                var newPassword = "newPassword123".ToSecureString(true);
                await userManagement.ResetPassword(loginResult.Item2, loginResult.Item1, newPassword, recoveryKey);
                Console.WriteLine("Password reset successfully.");

                // Logout user (Remove if testing remove account, you need to be logged in to remove your acc)
                await userManagement.LogoutUser(loginResult.Item2, loginResult.Item1);
                Console.WriteLine("User logged out.");

                // Remove account
                await userManagement.RemoveAccount(loginResult.Item2, loginResult.Item1);
                Console.WriteLine("Account removed successfully.");
            }

PariahCybersecTest.AccountsWithSessionsTest

Tests all of the DataRequestTest system (Keep in mind you need to make a dummy exe that is running within the local path; this will be fixed based on a few thoughts i've gotten)

            public static async Task DataRequestTest()
            {

                var author = "Zakstar";
                var software = "TournamentOfBullets";
                var serviceParent = "GunGaleOnline";
                var programName = "GunGaleOnlineLauncher";
                var password = "TestPassword123!".ToSecureString(true);
                var identifier = "Gun Gale Online".ToSecureString(true);
                var username = "Launcher";
                var tierCount = 1;

                // Simulated PublicKey (normally this would be a PQC public key)
                var publicKey = "SimulatedPublicKeyShouldBe32CharsLong".ToSecureString(true);

                var manager = new Pariah_Cybersecurity.DataHandler.DataRequest();

                // Test: GetPaths
                var directoryData = await manager.GetPaths(identifier, software, author, programName, serviceParent);
                Console.WriteLine("GetPaths test completed.");

                var createdSystem = await manager.CreateNewSystem(username, identifier, password, software, author, "DummyExePath", serviceParent, tierCount, publicKey);
                Console.WriteLine($"CreateNewSystem returned: {createdSystem.ConvertToString()}");

                // Test: CreateNewApp
                var createdApp = await manager.CreateNewApp("Tower Of Bullets", password, directoryData.MainServicePath, directoryData, "0", publicKey);
                Console.WriteLine($"CreateNewApp returned: {createdApp.ConvertToString()}");



                // Test: CheckMainPathValidity
                var validityCheck = await manager.CheckMainPathValidity(directoryData, publicKey);
                Console.WriteLine($"CheckMainPathValidity: {validityCheck}");

                // Test: ValidateProgram
                var validate = await manager.ValidateProgram(directoryData, programName, publicKey);
                Console.WriteLine($"ValidateProgram: {validate}");




            }

PariahCybersecTest.DataRequestTest

This uses KYBERS CRYSTAL for handling secrets; this is great for one time passes, exchanges, etc.

Types

KeyAndEncryptedText

Holds AES-GCM encrypted data and its associated IV.

  • Fields:
    • byte[] key: Kyber Encapsulated Secret.
    • byte[] text: Kyber Encapsulation Data

Methods

Initiate()

Creates a public and private key (tuple.Item1, tuple.Item2). The public key should be shared, but the private key should only be on the the device that made/called the function.

  • Returns: Dictionary<string, byte[]>, Dictionary<string, byte[]>

CreateSecret (Dictionary<string, byte[]> givenkey)

Creates a secret using the public key, returning a KeyAndEncryptedText object; check this when fixing example section

  • Parameters:

    • givenkey: The public key, encoded as a KyberPublicKeyParameters.
  • Returns: Task<byte[]>


CreateSecretTwo(Dictionary<string, byte[]> privkey, byte[] cipher)

Creates a second secret using the private key and a cipher (within the KeyAndEncryptedText object as key).

  • Parameters:

    • privkey: The private key, encoded as a KyberPrivateKeyParameters .
    • cipher: The Dilithium signature created with CreateSignature()..
  • Returns: Task


EasyPQC.Keys

Rotation Class

The Rotation class is responsible for generating and rotating session keys, typically used to create a new session key by hashing a base key multiple times with salt for enhanced security.

Methods

CreateInitialKey(string key)

Generates an initial key and salt combination. The key is hashed using the ShakeDigest (SHAKE256) algorithm 1000 times along with a randomly generated salt. The resulting key and salt are returned as Base64-encoded strings.

  • Parameters:
    • key: The base key to be hashed (usually Base64-encoded).
  • Returns: Task<(string, string)>: A tuple containing the salt (Base64-encoded) and the generated key (Base64-encoded).

RotateKey(SecureString key, int rotations, string salt)

Rotates an existing key multiple times based on the number of rotations specified. Each rotation involves hashing the key and the salt using the ShakeDigest algorithm. After the specified number of rotations, the resulting key is returned as a Base64-encoded string.

  • Parameters:
    • key: The current session key, provided as a SecureString.
    • rotations: The number of times the key should be rotated (hashed).
    • salt: The salt used in the key rotation process.
  • Returns: Task: The rotated session key as a Base64-encoded string.

ToBase64(string input)

Converts an input string to a Base64-encoded string.

  • Parameters:
    • input: The string to be converted to Base64.
  • Returns: string: The Base64-encoded version of the input string.
EasyPQC.Rotation

This uses Dilithium for creating fingerprints, commonly used for ensuring data hasn't been tampered!

Methods

CreateKeys()

Creates a public and private key asynchronously (tuple.Item1, tuple.Item2). The public key should be shared, but the private key should only be on the the device that made/called the function.

  • Returns: Task<(Dictionary<string, byte[]>, Dictionary<string, byte[]>)>

CreateSignature (Dictionary<string, byte[]> privatekeyBytes, string input)

Creates a signature asynchronously through a private key and an input.

  • Parameters:

    • privatekeyBytes: The private key in byte array form.
    • input: The string meant to be signed,
  • Returns: Task<byte[]>


VerifySignature(Dictionary<string, byte[]> publickeyBytes, byte[] signature, string input)

Verifies the input data using the public key, the saved signature and a reference input as a string.

  • Parameters:

    • publickeyBytes: The public key in byte array form.
    • signature: The Dilithium signature created with CreateSignature()..
    • input: The string meant to be validated,
  • Returns: Task


VerifySignature(Dictionary<string, byte[]> publickeyBytes, byte[] signature, byte[] inputBytes)

Verifies the input data using the public key, the saved signature and a reference input as a byte array.

  • Parameters:

    • publickeyBytes: The public key in byte array form.
    • signature: The Dilithium signature created with CreateSignature()..
    • input: The byte array meant to be validated,
  • Returns: Task


EasyPQC.Signatures

Packs and unpacks a file (be sure to set filepath, filepath2 and output!)

      public void FileTest()
      {

          var filePath = @"C/finally-all-the-chin-woo-artworks-in-high-quality-v0-f5bnem4v03oe1.png";

          var filePath2 = @"images.jfif";

          var fileOutput = @"TestFiles";

          // Generate a valid key pair
          var (publicKey, privateKey) = EasyPQC.Signatures.CreateKeys().Result;

          // Pack the file
          var pack = EasyPQC.FileOperations.PackFiles(
              filePath,
              fileOutput,
              Encoding.UTF8.GetBytes("Test"), // Use a valid private key
              "Password".ToSecureString(true), // SecureString for encryption
              null,
              EasyPQC.FileOperations.CompressionLevel.Fast,
              true
          ).Result;

          Console.WriteLine("Packed file: " + pack);

          // Unpack the file
          var unpack = EasyPQC.FileOperations.UnpackFile(
              pack,
              fileOutput,
              Encoding.UTF8.GetBytes("Test"), // Use the corresponding public key
              null,
              EasyPQC.FileOperations.CompressionLevel.Fast,
              "Password".ToSecureString(true) // SecureString for decryption
          ).Result;

          Console.WriteLine("Unpacked file: " + unpack);

          // Test with a wrong password
          var falseUnpack = EasyPQC.FileOperations.UnpackFile(
              pack,
              fileOutput,
              Encoding.UTF8.GetBytes("Test"), // Use the corresponding public key
              null,
              EasyPQC.FileOperations.CompressionLevel.Fast,
              "WrongPassword".ToSecureString(true) // Incorrect SecureString
          ).Result;

          Console.WriteLine("Unpacked file with wrong password: " + falseUnpack);
      }

EasyPQCTest.FileTest

A fun way to imagine how the key system would be used for a Matrix style client

    public void KeysMsgTest()
    {
        var members = new[] { "Kirito", "Asuna", "Klein", "Lisbeth", "Silica" };
        var publicKeys = new Dictionary<string, Dictionary<string, byte[]>>();
        var privateKeys = new Dictionary<string, Dictionary<string, byte[]>>();

        // Step 1: Everyone generates a keypair
        foreach (var member in members)
        {
            var keys = EasyPQC.Keys.Initiate();
            publicKeys[member] = keys.Item1;
            privateKeys[member] = keys.Item2;
        }

        Console.WriteLine("Everyone has generated their keys!\n");

        // Step 2: Everyone (except Kirito) establishes a shared key with Kirito
        foreach (var member in members)
        {
            if (member == "Kirito") continue;

            var shared = EasyPQC.Keys.CreateSecret(publicKeys["Kirito"]);
            var sharedSecret = shared.key;

            Console.WriteLine($"🔐 {member} → Kirito:");
            Console.WriteLine($"  Shared Secret: {Convert.ToBase64String(sharedSecret)}");

            // Simulating message send using the shared key
            Console.WriteLine($"  Message from {member}: \"Hey Kirito, let's meet up at the mall!\"\n");
        }

        Console.WriteLine("SAO Mall Chat setup complete! 🎉");
    }

EasyPQCTest.KeysMsgTest

Initiates the keys system, then creates secrets one and two.

         public void KeysTest()
         {
             var keyPass = "This is a test password!";

             var keys = EasyPQC.Keys.Initiate();


             var secretOne = EasyPQC.Keys.CreateSecret(keys.Item1);

             var sOnea = secretOne.text;
             var sOneb = secretOne.key;

             Console.WriteLine(Environment.NewLine);

             Console.Write("Secret One: " + Convert.ToBase64String(sOnea));
             Console.WriteLine(Environment.NewLine);
             Console.Write("Key One: " + Convert.ToBase64String(sOneb));

             var SecretTwo = EasyPQC.Keys.CreateSecretTwo(keys.Item2, sOnea);

             Console.WriteLine(Environment.NewLine);


             Console.WriteLine("Secret Validation " + Convert.ToBase64String(SecretTwo));


         }

EasyPQCTest.KeysTest

Creates an initial key before rotating it 20 times.

  public async Task RotateTest()
  {

      var rotation = new EasyPQC.Rotation();
      Console.WriteLine("Initial Key");
      var initkey = await rotation.CreateInitialKey("I need more power.");
      Console.WriteLine("Initial Salt: " + initkey.Item1);
      Console.WriteLine("Initial Key: " + initkey.Item2);

      var rot = new EasyPQC.Rotation();

      //Multirotation test

      int rotationCount = 20;

      int round = 0;

      string currentKey = initkey.Item2;

      while (rotationCount >= round)
      {
          var rotatedKey = await rot.RotateKey(currentKey.ToSecureString(true), round, initkey.Item2);
          Console.WriteLine($"Rotated Key for round {round}: " + rotatedKey);
          round++;
      }

EasyPQCTest.RotateTest

Creates two keys and a signature, before testing both VerifySignature methods.

           public async Task SignatureTest()
           {
               // Generate key pair
               var (publicKeyDict, privateKeyDict) = await EasyPQC.Signatures.CreateKeys();
               var message = "This is a test message.";

               // Encode and display key data
               Console.WriteLine("Public Key (Base64):");
               foreach (var kv in publicKeyDict)
                   Console.WriteLine($"{kv.Key}: {Convert.ToBase64String(kv.Value)}");

               Console.WriteLine("\nPrivate Key (Base64):");
               foreach (var kv in privateKeyDict)
                   Console.WriteLine($"{kv.Key}: {Convert.ToBase64String(kv.Value)}");

               Console.WriteLine();

               // Create signature
               var signature = await EasyPQC.Signatures.CreateSignature(privateKeyDict, message);
               Console.WriteLine("Signature (Base64): " + Convert.ToBase64String(signature));
               Console.WriteLine();

               // Verify signature
               var isValid = await EasyPQC.Signatures.VerifySignature(publicKeyDict, signature, message);
               Console.WriteLine("Signature valid Test Result: " + isValid);
               Console.WriteLine();

               // Verify with an invalid message
               var invalidMessage = "InvalidSignature";
               var invalidTest = await EasyPQC.Signatures.VerifySignature(publicKeyDict, signature, Encoding.UTF8.GetBytes(invalidMessage));
               Console.WriteLine("Invalid Signature Test Result: " + invalidTest);
               Console.WriteLine("\n\n");



               int i = 0;

               while (12 <= i)
               {
                   Console.WriteLine(Environment.NewLine);
                   i++;

               }

               Console.WriteLine("Summary:");
               Console.WriteLine("Signature valid Test Result: " + isValid);
               Console.WriteLine("Invalid Signature Test Result: " + invalidTest);

           }

EasyPQCTest.SignatureTest

EasyPQC (Or Easy Post Quantum Cryptography) is a C# class focused on more social aspects of cryptography (Such as secret passing and the like. This contains four parts you should be looking at;

and three functions


WriteAllBytesAsync(string path, byte[] bytes, Action? progressCallback = null, CancellationToken cancellationToken = default)

Same as the method above, but with support for cancellation using a CancellationToken.

  • Parameters:
    • path: The destination file path.
    • bytes: The byte array to write.
    • progressCallback: (Optional) Reports write progress.
    • cancellationToken: (Optional) Token to cancel the write operation.
  • Returns: Task
  • Throws: OperationCanceledException if cancellation is requested during the operation.
  • Example:

csharp
using var cts = new CancellationTokenSource();
await FileUtils.WriteAllBytesAsync("output.dat", myData, progress => Console.WriteLine(progress), cts.Token);


ReadAllBytesAsync(string path)

Reads all bytes from the specified file asynchronously using a buffered approach.

  • Parameters:
    • path: The path to the file to read.
  • Returns: Task<byte[]>: A byte array containing the file contents.
  • Example:

csharp
byte[] data = await FileUtils.ReadAllBytesAsync("input.dat");


Notes

  • All methods use a 4096-byte buffer to balance performance and memory usage.
  • The write methods are especially suitable for large files when used with progress feedback and cancellation.
  • Be sure to handle exceptions related to I/O operations (e.g., file not found, permission denied, disk full).

Here's an example of how this would work;

One of my hardest scripts, but this has key turning in it (Constnatly making an encryption key available to everyone that's part of the group)

  • First, the leader creates a Kyber public private key pair and the public key is shared

  • Everyone uses the public key to create a key encapsulation, this is our session key

  • We encrypt the session key using AES256GCM and give it to everyone

  • Everyone signs their key using Dilithium, then when a message is sent we always verify it

  • When a message is sent, we encrypt the message with the current version of the session key

  • A nonce is created/signed for every message (contains a counter, the username, previous session key and message hash)

  • Automatically we know the user is the user if the nonce is able to be both decrypted and read

  • The session key is evolved with SHAKE256

  • After an interval (could be time or amount of messages), we create a new kyber key, with dilithium used for authenticity (rotation)

The below will be handled in PariahNetworking (AKA Spire), possibly after the release of Database Designer

  • If someone was removed or left, we reauthenticate everyone who is active in the last hour
  • If someone is added or talks, they go through SectionA (public/private key)
  • Instead of rotating and switching everyone, it might be worth it to store user references as their name + their lave/join amount + rotation
  • This way, instead of doing complex and intensive things we can just make sure the user needs a new key if they rejoin
  • f they leave, others can still then see their messages without someone being able to act like they're them and stuff
  • When someone new joins or someone is removed, we simply rotate with them
Notes
  • Offline messages are handled as session keys are stored on a sender's device
  • The keys are then given to the recepient when they're back, with the public kyber key for delivery, signed with Dilitium
  • We have an action function that handles roles, messages, etc.
  • Also need CRDT and Audit Log with both being used to verify a sent in session
  • I'm not sure if for searching for messages and stuff it'll use Homomorphic Encryption or something yet
EasyPQC

Types

PackedFile

Represents a file that has been packed (compressed and optionally encrypted) with its associated signature.

  • Fields:

    • string FilePath: The path of the packed file.
    • string Signature: The signature of the packed file, usually encrypted.
  • Methods:

    • ToString(): Converts the PackedFile to a string representation in the format FilePath|Signature.
    • static PackedFile FromString(string packedFileString): Creates a PackedFile instance from a string representation.

CompressionLevel

Defines the level of compression for LZ4 compression.

  • Values:
    • Fast: Fast compression.
    • Balanced: Balanced compression.
    • Max: Maximum compression.

CompressionProgress

Delegate for reporting the progress of a file compression or decompression operation.

  • Parameters:
    • long current: The current position of the operation.
    • long fileSize: The total size of the file.
    • int percentage: The percentage of completion.

Methods

CompressFileAsync(string fileInput, string fileOutput, CompressionProgress compressionProgress, CompressionLevel compressionType)

Compresses a file asynchronously using LZ4 and reports progress.

  • Parameters:

    • fileInput: The input file path.
    • fileOutput: The output file path.
    • compressionProgress: A delegate for progress reporting.
    • compressionType: The level of compression to use.
  • Returns: Task: The path to the compressed file.


DecompressFileAsync(string fileInput, string fileOutput, CompressionProgress compressionProgress, CompressionLevel compressionType)

Decompresses a file asynchronously using LZ4 and reports progress.

  • Parameters:

    • fileInput: The input file path.
    • fileOutput: The output file path.
    • compressionProgress: A delegate for progress reporting.
    • compressionType: The level of compression to use.
  • Returns: Task: The path to the decompressed file.


HashFile(Stream fileData)

Hashes a file asynchronously using Blake3.

  • Parameters:

    • fileData: The stream containing the file data to hash.
  • Returns: Task<byte[]>: The computed hash of the file.


VerifyHash(Stream fileData, byte[] signature)

Verifies the integrity of a file by comparing its hash to a provided signature.

  • Parameters:

    • fileData: The stream containing the file data to verify.
    • signature: The signature to compare the hash against.
  • Returns: Task: true if the hash matches the signature, otherwise false.


PackFiles(string fileInput, string fileOutput, byte[] privateKey, SecureString sessionkey, CompressionProgress compressionProgress, CompressionLevel compressionType, bool encryptFile)

Compresses a file, creates a signed hash, and optionally encrypts the file.

  • Parameters:

    • fileInput: The input file path.
    • fileOutput: The output directory for the packed file.
    • privateKey: The private key for signing the file hash.
    • sessionkey: The session key for encryption (if applicable).
    • compressionProgress: A delegate for progress reporting.
    • compressionType: The level of compression to use.
    • encryptFile: Whether to encrypt the packed file.
  • Returns: Task: A PackedFile containing the packed file and its signature.


UnpackFile(PackedFile inputFile, string outputPath, byte[] publicKey, CompressionProgress compressionProgress, CompressionLevel compressionType, SecureString sessionkey)

Unpacks and decompresses a file, verifying its signature and decrypting it if necessary.

  • Parameters:

    • inputFile: The packed file to unpack.
    • outputPath: The directory where the unpacked file should be saved.
    • publicKey: The public key for signature verification.
    • compressionProgress: A delegate for progress reporting.
    • compressionType: The level of compression used.
    • sessionkey: The session key for decryption (if applicable).
  • Returns: Task: true if the file was successfully unpacked and verified, otherwise false.


EasyPQC.FileOperations

PasswordGenerator Class

Generates secure random passwords based on customizable criteria (character sets and length), has a singular function;

PasswordGenerator

GeneratePassword(int length, bool includeLowercase, bool includeUppercase, bool includeDigits, bool includeSpecialChars)

Generates a random password using the specified character types and length.

  • Parameters:

    • length: Total number of characters in the generated password. Must be > 0.
    • includeLowercase: Whether to include lowercase letters (a–z).
    • includeUppercase: Whether to include uppercase letters (A–Z).
    • includeDigits: Whether to include digits (0–9).
    • includeSpecialChars: Whether to include symbols (!@#$%^&*()-_=+[]{}|;:',.<>?).
  • Returns: string — The generated password.

  • Exceptions:

    • ArgumentException if length < 1 or no character sets are selected.
PasswordGenerator.GeneratePassword

Walker.Crypto offers simple/easy AES256GCM based cryptography! There are three different classes you should be looking at:

Walker.Crypto

A fun little function for encrypting and decrypting a file with AES256GCM.

Values

ChunkSize

An integer representing the size of each chunk encrypted (in this case 4418.)

Methods

EncryptFileAsync(string inputPath, string outputPath, SecureString password, Action progress = null)

Encrypts a file asynchronously using AES-GCM. Reads the input file in chunks, encrypts each chunk, and writes the result to the output file.

  • Parameters:

    • inputPath: Path of the file to encrypt.
    • outputPath: Path where the encrypted file will be saved.
    • password: Secure password to derive the encryption key.
    • progress: Optional callback for progress tracking, with a value from 0.0 to 1.0.
  • Returns: Task


DecryptFileAsync(string inputPath, string outputPath, SecureString password, Action progress = null)

Decrypts an encrypted file asynchronously. Reads the encrypted file in chunks, decrypts each chunk, and writes the result to the output file.

  • Parameters:

    • inputPath: Path of the encrypted file.
    • outputPath: Path where the decrypted file will be saved.
    • password: Secure password to derive the decryption key.
    • progress: Optional callback for progress tracking.
  • Returns: Task

Walker.Crypto.AESFileEncryptor

Provides async-based AES-GCM encryption and decryption with password-derived keys. Includes file encryption helpers, progress tracking, and byte array support.

Types

AESEncryptedText

Holds AES-GCM encrypted data along with the IV.

  • Fields:

    • string IV: Base64-encoded initialization vector.
    • string EncryptedText: Base64-encoded ciphertext.
  • Methods:

    • string ToString(): Converts the encrypted data to the format IV|EncryptedText.
    • static AESEncryptedText FromUTF8String(string input): Parses the string in IV|EncryptedText format. Throws FormatException if invalid.

Methods

EncryptAsync(string plainText, SecureString password, Action progress = null)

Encrypts plain text using AES-GCM asynchronously. Returns an AESEncryptedText containing the IV and encrypted data.

  • Parameters:

    • plainText: Text to encrypt.
    • password: Secure password to derive the encryption key.
    • progress: Optional callback for progress tracking, with a value from 0.0 to 1.0.
  • Returns: Task


DecryptAsync(SimpleAESEncryption.AESEncryptedText encrypted, SecureString password, Action progress = null)

Decrypts an AESEncryptedText asynchronously and returns the result as a string.

  • Parameters:

    • encrypted: The encrypted data and IV.
    • password: Secure password to derive the decryption key.
    • progress: Optional callback for progress tracking.
  • Returns: Task


DecryptAsync(string encryptedText, string ivBase64, SecureString password, Action progress = null)

Decrypts a string with a given IV asynchronously using the provided password.

  • Parameters:

    • encryptedText: Base64-encoded encrypted data.
    • ivBase64: Base64-encoded IV.
    • password: Secure password to derive the decryption key.
    • progress: Optional callback for progress tracking.
  • Returns: Task


EncryptBytesAsync(byte[] data, SecureString password, Action progress = null)

Encrypts a byte array asynchronously. Returns the encrypted data wrapped in an AESEncryptedText.

  • Parameters:

    • data: The byte array to encrypt.
    • password: Secure password to derive the encryption key.
    • progress: Optional callback for progress tracking.
  • Returns: Task


DecryptBytesAsync(SimpleAESEncryption.AESEncryptedText encrypted, SecureString password, Action progress = null)

Decrypts an AESEncryptedText asynchronously and returns the result as a byte array.

  • Parameters:

    • encrypted: The encrypted data and IV.
    • password: Secure password to derive the decryption key.
    • progress: Optional callback for progress tracking.
  • Returns: Task<byte[]>

Walker.Crypto.AsyncAESEncryption

Provides simple, sync-based AES-GCM encryption and decryption with a key derived from a password. Includes helpers for secure key generation and basic parsing.

Types

AESEncryptedText

Holds AES-GCM encrypted data and its associated IV.

  • Fields:

    • string IV: Base64-encoded initialization vector.
    • string EncryptedText: Base64-encoded ciphertext.
  • Methods:

    • string ToString(): Converts the data to a string using the format IV|EncryptedText.
    • static AESEncryptedText FromUTF8String(string input): Parses a string in the IV|EncryptedText format. Throws FormatException if the input is invalid.

Methods

Encrypt(string plainText, SecureString password)

Encrypts plain text using AES-GCM. Outputs both the encrypted content and IV.

  • Parameters:

    • plainText: Text to encrypt.
    • password: Used to derive a 256-bit key.
  • Returns: AESEncryptedText


Decrypt(AESEncryptedText encrypted, SecureString password)

Decrypts a previously encrypted value using its IV and the original password. Returns a secure string.

  • Parameters:

    • encrypted: The encrypted payload and IV.
    • password: Used to derive the decryption key.
  • Returns: SecureString


Decrypt(string encryptedText, string ivBase64, SecureString password)

Takes the raw Base64 ciphertext and IV, decrypts it using the password, and returns the plain string.

  • Parameters:

    • encryptedText: Base64 string of the ciphertext.
    • ivBase64: Base64 IV.
    • password: The password to derive the key.
  • Returns: string


GenerateRandomBytes(int size)

Creates a secure random byte array of the given size.

  • Parameters:

    • size: How many bytes to generate.
  • Returns: byte[]


DeriveKey(SecureString password, int keyBytes)

Hashes the password with SHA-256 and adjusts the result to the specified byte length.

  • Parameters:

    • password: The password to derive from.
    • keyBytes: The size of the final key in bytes.
  • Returns: byte[]

Walker.Crypto.SimpleAESEncryption

Encrypts a file before decrypting it.

            public async Task<string> AESFileEcryptorTest()
            {
                var password = "ShadowLord".ToSecureString(true);

                string inputFilePath = @"TestFiles\finally-all-the-chin-woo-artworks-in-high-quality-v0-tgmaxu5u03oe1.png";
                string encryptedFilePath = @"TestFiles\finally-all-the-chin-woo-artworks-in-high-quality-v0-tgmaxu5u03oe1_encrypted.png";
                string decryptedFilePath = @"TestFiles\finally-all-the-chin-woo-artworks-in-high-quality-v0-tgmaxu5u03oe1_decrypted.png";

                // Encrypt the file and report progress to the console
                double encryptionProgress = 0.0;

                await AESFileEncryptor.EncryptFileAsync(inputFilePath, encryptedFilePath, password, progress =>
                {
                    encryptionProgress = progress;
                    Console.WriteLine("Encryption Progress: " + (progress * 100) + "%");
                });

                Console.WriteLine("Encrypted file saved at: " + Path.GetFullPath(encryptedFilePath));

                // Decrypt the file and report progress to the console
                double decryptionProgress = 0.0;
                Console.WriteLine("Starting file decryption...");
                await AESFileEncryptor.DecryptFileAsync(encryptedFilePath, decryptedFilePath, password, progress =>
                {
                    decryptionProgress = progress;
                    Console.WriteLine("Decryption Progress: " + (progress * 100) + "%");
                });
                Console.WriteLine("Decrypted file saved at: " + Path.GetFullPath(decryptedFilePath));

                Console.WriteLine(Environment.NewLine);
                Console.WriteLine(Environment.NewLine);
                return "Done";
            }

WalkerCryptoTest.AESFileEcryptorTest

Encrypts a string using SimpleAESEncryption.Encrypt and decrypts with SimpleAESEncryption.Decrypt before doing the same with the async methods and a tracking method

        public async Task<string> SimpleAESEncryptionTest()
        {
            var password = "ShadowLord".ToSecureString(true);


            var encryptasynctest = SimpleAESEncryption.Encrypt("This is a test string.", password);
            Console.WriteLine("Encrypted string (SimpleAESEncryptionTest): " + encryptasynctest);

            Console.WriteLine(encryptasynctest.IV);
            Console.WriteLine(encryptasynctest.EncryptedText);


            var decryptasynctest = SimpleAESEncryption.Decrypt(encryptasynctest, password);
            Console.WriteLine("Decrypted string (SimpleAESEncryptionTest): " + decryptasynctest);




            double progressPercentage = 0.0;

            var enctest1 = await AsyncAESEncryption.EncryptAsync("This is a test string.", password, progress =>
            {
                progressPercentage = progress;
                Console.WriteLine("Progress: " + progressPercentage + "%");
            });

            Console.WriteLine("Encrypted string (SimpleAESEncryptionTest): " + enctest1);


            var decryptPercentage = 0.0;

            var dectest1 = await AsyncAESEncryption.DecryptAsync(enctest1, password, progress =>
            {
                decryptPercentage = progress;
                Console.WriteLine("Decryption Progress: " + decryptPercentage + "%");
            });

            Console.WriteLine("Decrypted string(SimpleAESEncryptionTest): " + dectest1);

            Console.WriteLine(Environment.NewLine);
            Console.WriteLine(Environment.NewLine);
            return "Done";





        }

WalkerCryptoTest.SimpleAESEncryptionTest

Ensures that a wrong password can't be used (Was a huge issue during testing, requiring a lot of the file logic in AESFileEncryptor to be rewritten)

           public async Task WrongAESFilePasswordTest()
           {
               try
               {
                   var password = "ShadowLord".ToSecureString(true);

                   string inputFilePath = @"TestFiles\finally-all-the-chin-woo-artworks-in-high-quality-v0-tgmaxu5u03oe1.png";
                   string encryptedFilePath = @"TestFiles\finally-all-the-chin-woo-artworks-in-high-quality-v0-tgmaxu5u03oe1_encrypted.png";
                   string decryptedFilePath = @"TestFiles\finally-all-the-chin-woo-artworks-in-high-quality-v0-tgmaxu5u03oe1_decrypted.png";

                   // Encrypt the file and report progress to the console
                   double encryptionProgress = 0.0;

                   await AESFileEncryptor.EncryptFileAsync(inputFilePath, encryptedFilePath, password, progress =>
                   {
                       encryptionProgress = progress;
                       Console.WriteLine("Encryption Progress: " + (progress * 100) + "%");
                   });

                   Console.WriteLine("Encrypted file saved at: " + Path.GetFullPath(encryptedFilePath));

                   // Decrypt the file and report progress to the console
                   double decryptionProgress = 0.0;
                   Console.WriteLine("Starting file decryption...");
                   await AESFileEncryptor.DecryptFileAsync(encryptedFilePath, decryptedFilePath, "WrongPassword".ToSecureString(true), progress =>
                   {
                       decryptionProgress = progress;
                       Console.WriteLine("Decryption Progress: " + (progress * 100) + "%");
                   });
                   Console.WriteLine("Decrypted file saved at: " + Path.GetFullPath(decryptedFilePath));

                   Console.WriteLine(Environment.NewLine);
                   Console.WriteLine(Environment.NewLine);
               }

               catch
               {
                   Console.WriteLine("Bad password");
               }
           }

WalkerCryptoTest.WrongAESFilePasswordTest

Pariah Cybersec (3).png

What is Pariah Cybersecurity?

Pariah Cybersecurity is a .NET 8.0 Based Library. Primarily developed for programs like the XRUIOS, Project Replicant and Database Designer, it contains a suite of tools meant to make development both easy and secure for developers of all levels!

This is fully open source and free forever! It was made to target Windows, Linux and MacOS!

💻 Code By WalkerDev

WalkerDev
"Loving Coding Is Intrinsically The Same As Hating Yourself"
> His Discord

🎨 Art By Kennaness

Ada
"When Will I Get My Isekai"
> Her Bluesky

## [View The Github Project!](https://github.com/Walker-Industries-RnD/PariahCybersecurity)

(Note, there are many comments all around; you'll see as time continued they decreased in quality and quantity. I plan on adding more comments again at a later time, but I currently have other projects I would like to focus on! There are a few functional updates which will come later, but after SecureString is fixed, everything should be fine to use in production!)

What's Included?

🔐Walker.Crypto.Keys.AsyncAESEncryption - Easy To Use AES256-GCM Based Encryption
📄JSONDataHandler - A Simple Yet Powerful Method Of Writing, Saving and Getting Data
🗝️SecretManager - A Local Based Secrets Manager
📨DataRequest - For Creating, Storing and Getting Data Readable By Other Programs Securely
👤Accounts - A Barebones Example Of A Local Based Account System
🔐AccountsWithSessions - A Secure, Local Based Account System With Session Verification

And Much, Much More!

Check the Find The Right Solution For You! Page To Learn More! This also acts as the table of contents!
You Can Also Use The Pariah's Codex of Autonomous Instruments To View Almost All Pariah Focused Functions!
Finally, you can view examples directly within The Pariah's Grimoire of Applied Functionality!

How Do I Use It?

Let's say you have some data you want to save, like

var YareliGallery = List<Custom.ImageObj>`

With Pariah Cybersecurity, all you have to do is

//Create a new Pariah Object on Disc
await JSONDataHandler.CreateJsonFile(pathToSaveTo, "Yareli Gallery", new JObject {} );
//Load the PariahJSON you just made
var loadedGalleryFile = await JSONDataHandler.LoadJsonFile(pathToSaveTo, "Yareli Gallery");
//Add the gallery list to the PariahJson
var savedGallery = await JSONDataHandler.AddToJson<List<Custom.ImageObj>>(loadedGalleryFile, "Gallery", YareliGallery, Password);
//Save the PariahJSON
await JSONDataHandler.SaveJson(savedGallery);

Now, whenever you want to get your variable, all you need to do is use

//Load the PariahJson from disc
var loadedGalleryFile = await JSONDataHandler.LoadJsonFile(pathToSaveTo, "Yareli Gallery");
//Get the GalleryFile value
var loadedGallery = await JSONDataHandler.GetVariable<List<Custom.ImageObj>>(loadedGalleryFile, "Gallery", Password);

Keep in mind; there are a lot of systems within Pariah. Go to the Examples Directory and you can see specific examples for the library you'll be using!

Prerequisites

The Following Are Needed To Use All Of Pariah Cybersecurity:

  • BouncyCastle.NetCore
  • Ceras
  • k4os.Compression.LZ4
  • Konscious.Security.Cryptography.Argon2
  • Newtonsoft.Json
  • Parquet.Net

Changes, Fixes And Future Developments

  • Changing SecureString to use a custom char[] or byte[] based system (The current SecureString has a length limit, immediate fix needed)
  • Readding one of the disabled signatures to the account with session system (Should still be secure without)
  • Package Dependencies Into Singular DLL
  • Adding more graceful error handling (Ha, like that's happening)
  • Releasing Pariah Cybersecurity's password manager as an example

Special Thanks

  • To Kennaness for helping out between making art, hearing my code crash outs and being a good bud
  • My friends for supporting me through the development process
  • The Walker Industries' community on Discord for their support

License

This project is licensed under the NON-AI Mozilla Public License Version 2.0.

Welcome To Pariah Cybersecurity

Table Of Contents

Note: While most things have documentation, I didn't bother making documentation for the smaller things that don't have as much precedence (Like the Ceras formatters for EasyPQC)

Please read the important note at the bottom of the page!

🔑EasyPQC

Simple, Easy To Use Post Quantum Based Cryptography Tools

Title Description Function #
EasyPQC.Signatures Dilithium Based Signing 8
EasyPQC.Keys KYBERS CRYSTAL Based Public/Private Pairs 8
EasyPQC.FileOperations LZ4 Compression, Blake3 Signing and AES Cryptography All In One 9
EasyPQC.Rotation SHAKE256 Based Password Rotation 3

🛡️ Walker.Crypto

Easy To Use AES256-GCM Based Encryption

Title Description Function #
Walker.Crypto.SimpleAESEncryption Sync Based AES256-GCM Cryptography 6
Walker.Crypto.AsyncAESEncryption Async Based AES256-GCM Cryptography 5
Walker.Crypto.AESFileEncryptor A Simple Method To Encrypt and Decrypt Files 2

PasswordGenerator

Self Explanitory

Title Description Function #
PasswordGenerator.GeneratePassword Random String Based Generation 1

Note; everything after is within the DataHandler Class (DataHandler.JSONDataHandler, DataHandler.PasswordHandler, etc.)

📦 DataHandler

Modular Tools for Data, Secrets, and Sessions

Title Description Function #
DataHandler.JSONDataHandler Easy JSON Based File Handling (Highly Suggest) 8
DataHandler.SaltAndHashing Password Creation And Verification with Argon2 5+
DataHandler.DataEncryptions Easy Data Based Packing and Unpacking 2
DataHandler.SecretManager Public Secret Rotation, Management and Migration 10+
DataHandler.DeviceIdentifier Device Fingerprinting Tool 2
DataHandler.DataRequest Software to Software Based Data Communication Protocol 12+
DataHandler.Accounts Local User Creation, Login, and Recovery 5
DataHandler.AccountsWithSessions Session Based Local Account Management 10+
Title Description Function #
Utilities.Tools UUID and Random String Generators 2

BinaryConverter

Modular Tools for Data, Secrets, and Sessions

Title Description Function #
BinaryConverter Object/Byte Array Conversion Tools 4

IMPORTANT NOTE

IMPORTANT: There is a Ceras based binary serializer and a non Ceras based one; it's highly recommended to use the Ceras one for the time being due to it's speed compared to the non ceras method; the non ceras method will be fine as is right now, but using Ceras for all other operations will have a noticeable lag. A cofig must also be made for special items and classes; else errors at runtime appear (Look at Signatures and Keys' library, specifically Encode and Decode). In the future, all items will be turned to a byte array before being switched back to a ceras serialized item.

When using JSONDataHandler, ensure you have a parameterless constructor (as seen across the Accounts systems), else your classes will get errors. Example:

            public class EncryptedTier
            {
                public byte[] SignedEncryptedTier { get; set; }
                public string EncryptedTierPass { get; set; }
                public byte[] SignedTierPass { get; set; }

                public EncryptedTier() { } // Required for deserialization

                public EncryptedTier(byte[] signedEncryptedTier, string encryptedTierPass, byte[] signedTierPass)
                {
                    SignedEncryptedTier = signedEncryptedTier;
                    EncryptedTierPass = encryptedTierPass;
                    SignedTierPass = signedTierPass;
                }
            }

Finally, when using PariahJson, do not try to save libraries as weird tuples; as an example, during my debugging and testing I saw that

Dictionary<string, string>

Worked fine, whereas

Dictionary<string, (item, item2. item3)>

Would return null items on GetVariable. Instead, it's better to do something like

public class ItemHolder
{
	public string item1
	public string item2
	public string item3

	public ItemHolder() { } // Required for deserialization


}

Dictionary<string, itemHolder>


Find The Right Solution For You!

🛡️ Pariah Cybersecurity Suite Wiki

A comprehensive reference for all classes and functions in Pariah Cybersecurity


📚 Contents

  • 🔄 Binary Converter
  • 🔐 Walker Crypto
  • 🧠 Core: Pariah_Cybersecurity
    • 🔑 Password Generation & Hashing
    • 🧩 Data Handling
    • 🛡️ Secret Management
    • 🧬 Device Identification
    • 📦 Data Request
    • 👤 Account Systems
    • 🧰 Utilities
  • 🔐 EasyPQC (Post-Quantum Crypto)

🔄 Binary Converter

  • ObjectToByteArrayAsync
  • ByteArrayToObjectAsync
  • NCObjectToByteArrayAsync
  • NCByteArrayToObjectAsync

🔐 Walker.Crypto

🔒 Walker.Crypto.SimpleAESEncryption

  • AESEncryptedText
  • GenerateRandomBytes
  • DeriveKey
  • Encrypt
  • Decrypt

Walker.Crypto.AsyncAESEncryption

  • EncryptAsync
  • DecryptAsync
  • EncryptBytesAsync
  • DecryptBytesAsync

🗂 Walker.Crypto.AESFileEncryptor

  • EncryptFileAsync
  • DecryptFileAsync

🧠 Core: Pariah_Cybersecurity

🔑 Password Generation & Hashing

PasswordGenerator

  • GeneratePassword

DataHandler.SaltAndHashing

  • PasswordCheckData
  • PasswordHandler
    • GeneratePasswordHashAsync
    • ValidatePasswordAsync
    • Argon2_GetHashAsync
    • SlowEquals
  • BouncyCastleHashing

🧩 Data Handling

DataHandler.JSONDataHandler

  • PariahJSON
  • CreateJsonFile
  • LoadJsonFile
  • AddToJson
  • DeletefromJson
  • UpdateJson
  • GetVariable
  • CheckIfVariableExists
  • SaveJson

DataHandler.DataEncryptions

  • PackData
  • UnpackData

🛡️ Secret Management

DataHandler.SecretManager

  • PublicKeyFile
  • PublicKeyFileInit
  • CreateBank
  • CheckIfBankExists
  • GetPublicSecret
  • GetSecretRound
  • AddPublicSecret
  • DeletePublicSecret
  • GetAllSecretNames
  • RotateSecret
  • MigratePublicSecrets

🧬 Device Identification

DataHandler.DeviceIdentifier

  • GetBoardSerialAsync
  • RunCommandAsync

📦 Data Request

DataHandler.DataRequest

  • SecuritySettings
  • DirectoryData
  • EncryptedTier
  • GetExecutablePathAsync
  • IsFileWithinDirectoryAsync
  • MakeRelativeFromAuthor
  • GetPaths
  • CheckMainPathValidity
  • ValidateProgram
  • CreateNewSystem
  • CreateNewApp
  • AddToBlacklist
  • RemoveFromBlacklist
  • RemoveAccount
  • VerifySessionIntegrity
  • Account System

👤 Account Systems

DataHandler.Accounts

  • ChangePublicKey
  • SetupFiles
  • CreateUser
  • LoginUser
  • ResetPassword

DataHandler.AccountsWithSessions

  • ActiveSession
  • ConnectedSessionReturn
  • ReturnCreateUser
  • SecuritySettings
  • AccountData
  • SetupFiles
  • CreateUser
  • LoginCore
  • LoginUser
  • ValidateSession
  • LogoutUser
  • RemoveAccount
  • ResetPassword
  • GetAllUsernames

🧰 Utilities

  • CreateUUID
  • GetRandomLengthString

🔐 EasyPQC (Post-Quantum Crypto)

🔏 EasyPQC.Signatures

  • CreateKeys
  • CreateSignature
  • VerifySignature
  • Encode
  • DecodePublic
  • DecodePrivate

🗝️ EasyPQC.Keys

  • KeyAndEncryptedText
  • Initiate
  • CreateSecret
  • CreateSecretTwo
  • Encode
  • DecodePublic
  • DecodePrivate

🗂 EasyPQC.FileOperations

  • PackedFile
  • CompressionLevel
  • CompressionProgress
  • CompressFileAsync
  • DecompressFileAsync
  • HashFile
  • VerifyHash
  • PackFiles
  • UnpackFile

🔁 EasyPQC.Rotation

  • CreateInitialKey
  • RotateKey
  • ToBase64

📄 IO Operations

  • WriteAllBytesAsync
  • ReadAllBytesAsync

💬 Chat (Draft + Guide)

  • Message Data
  • Message
  • Attachment Data

🧬 Merger

  • (N/A, Coming Soon)

The Pariah's Codex of Autonomous Instruments

These are examples I created while testing Pariah Cybersecurity! For some things (such as Pack and Unpack data) I skipped them, since they are used at least 50 times through testing within other functions!

PariahCybersec Tests

Note: Be sure to also include private readonly DataHandler.Accounts accounts = new DataHandler.Accounts();

The Pariah's Grimoire of Applied Functionality